package object2;


/**
 * 继承的细节
 */
public class ExtendsDetail {

    public static void main(String[] args) {
        /*
            1)子类继承了所有的属性和方法，非私有的属性和方法可以在子类直接访问，但是私有属性和方法不能直接访问，要
              通过父类提供公共的方法去访问
            2)子类必须调用父类的构造器，完成父类的初始化
            3)当创建子类对象时，不过使用子类的哪个构造器，默认情况下总会调用父类的无参构造器
              如果父类没有提供无参构造器，则必须在子类的构造器中用super去指定使用父类的哪个构造器完成对父类的初始化工作
            4)如果希望指定调用父类的某个构造器，则显式的调用下：super(参数列表)
            5)super在使用时，必须放在构造器的第一行(super只能在构造器中使用)
            6)super() 和 this() 都只能放在构造器第一行，因此这两个方法不能共存在一个构造器
            7)java所有类都是Object类的子类，Object是所有类的基类
            8)父类构造器的调用不限于直接父类 将一直往上追溯直到Object类(顶级父类)
            9)子类最多只能继承一个父类(直接继承),java是单继承机制
            10)不能滥用继承，子类和父类之间必须满足 is-a 的逻辑关系
         */

        System.out.println("===第一个对象===");
        Sub sub = new Sub();//创建了子类对象 Sub
//        System.out.println("===第二个对象===");
//        Sub sub2 = new Sub("jack");
//        System.out.println("===第三个对象===");
//        Sub sub3 = new Sub("king", 10);
        sub.sayOk();
    }
}

class Sub extends Base {

    public Sub(String name, int age) {

        //1.如果要调用父类Base的无参构造器
//        super();

        //2.如果要调用父类Base(String name)构造器
//        super("张三");

        //3.调用父类Base(String name, int age)构造器
//        super("king", 20);

        /*
            小细节：
            1)super 在使用时，必须放在构造器第一行
            2)super() 和 this() 都只能放在构造器第一行，因此这两个方法不能共存在一个构造器中
         */
        System.out.println("子类Sub(String name, int age)被调用...");
    }

    public Sub() {//无参构造器
        //super();默认调用父类的无参构造器
        super("smith", 10);
        System.out.println("子类Sub()构造器被调用...");
    }

    //当创建子类对象时，不管使用子类的哪个构造器，默认情况下总会调用父类的无参构造器
    public Sub(String name) {
        super("tom", 30);
        //do nothing...
        System.out.println("子类 Sub(String name)构造器被调用....");
    }

    public void sayOk() {
        //非私有的属性和方法可以在子类直接访问
        //私有属性和方法不能在子类中直接访问
        System.out.println(n1 + " " + n2 + " " + n3);

        test100();

        test200();

        test300();

        //test400();错误

        //要通过父类提供公共的方法去访问
        System.out.println("n4 = " + getN4());

        callTest400();//
    }
}

class Base extends TopBase {

    public int n1 = 100;

    protected int n2 = 200;

    int n3 = 300;

    private int n4 = 400;

    public Base() {//无参构造器
        System.out.println("父类Base()构造器被调用...");
    }

    public Base(String name) {//有参构造器
//        super();//默认super
        System.out.println("父类Base(String name)构造器被调用...");
    }

    public Base(String name, int age) {
        System.out.println("父类Base(String name, int age)构造器被调用...");
    }

    public int getN4() {
        return n4;
    }

    public void test100() {
        System.out.println("test100");
    }

    protected void test200() {
        System.out.println("test200");
    }

    void test300() {
        System.out.println("test300");
    }

    private void test400() {
        System.out.println("test400");
    }

    //call
    public void callTest400() {
        test400();
    }
}

class TopBase {// 父类是Object

    public TopBase() {

        super();//Object的无参构造
        System.out.println("构造器TopBase()被调用...");//1

    }
}